#!/bin/bash
###
 # @Description: etcd证书生成分发
 # @Author: 快乐就像...
 # @Date: 2021-07-21 16:05:01
 # @LastEditTime: 2021-08-09 11:11:23
 # @LastEditors: 快乐就像...
### 

# 使用 IP 或可解析的主机名替换 HOST0、HOST1 和 HOST2 等
export HOST0=ETCD_IP01
export HOST1=ETCD_IP02
export HOST2=ETCD_IP03
export HOST3=ETCD_IP04
export HOST4=ETCD_IP05

cfssl_init () {
    # 初始化cfssl
    unzip ./cfssl.zip
    mv ./cfssl/cfssl*  /usr/local/bin/
    chmod +x /usr/local/bin/cfssl*

    # etcd ca配置
    cat << EOF | tee ca-config.json
{
    "signing": {
        "default": {
            "expiry": "87600h"
        },
        "profiles": {
            "etcd": {
                "expiry": "87600h",
                "usages": [
                    "signing",
                    "key encipherment",
                    "server auth",
                    "client auth"
                ]
            }
        }
    }
}
EOF

    # etcd ca证书
    cat << EOF | tee ca-csr.json
{
    "CN": "etcd CA",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "ZJ",
            "L": "Hangzhou"
        }
    ]
}
EOF
    # 生成CA凭证和私钥
    cfssl gencert -initca ca-csr.json |cfssljson -bare ca

# etcd server证书
cat << EOF | tee server-csr.json
{
    "CN": "etcd",
    "hosts": [
    "127.0.0.1",
    "${HOST0}",
    "${HOST1}",
    "${HOST2}",
    "${HOST3}",
    "${HOST4}"
    ],
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "ZJ",
            "L": "Hangzhou"
        }
    ]
}
EOF

    # 生成etcd server证书
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd server-csr.json |cfssljson -bare server

# etcd client证书
cat << EOF | tee client-csr.json
{
    "CN": "client",
    "key": {
        "algo": "rsa",
        "size": 2048
    },
    "names": [
        {
            "C": "CN",
            "ST": "ZJ",
            "L": "Hangzhou"
        }
    ]
}
EOF

    # 生成etcd client证书
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=etcd client-csr.json |cfssljson -bare client


}

service_init () {
    # 创建临时目录来存储将被分发到其它主机上的文件
    mkdir -p ./${HOST0}/cert/ ./${HOST1}/cert/ ./${HOST2}/cert/ ./${HOST3}/cert/ ./${HOST4}/cert/

    ETCDHOSTS=("${HOST0}" "${HOST1}" "${HOST2}" "${HOST3}" "${HOST4}")
    NAMES=("etcd01" "etcd02" "etcd03" "etcd04" "etcd05")

    for i in "${!ETCDHOSTS[@]}"; do
    HOST=${ETCDHOSTS[$i]}
    NAME=${NAMES[$i]}

    cp ./*.pem  ./"${HOST}"/cert/
    cp ./etcd-v3.4.16-linux-amd64.tar.gz ./"${HOST}"/
    
    cat << EOF > ./"${HOST}"/etcd.conf
#[Member]
ETCD_NAME="${NAME}"
ETCD_DATA_DIR="/data/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://${HOST}:2380"
ETCD_LISTEN_CLIENT_URLS="https://${HOST}:2379,http://127.0.0.1:2379"

#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://${HOST}:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://${HOST}:2379"
ETCD_INITIAL_CLUSTER="${NAMES[0]}=https://${ETCDHOSTS[0]}:2380,${NAMES[1]}=https://${ETCDHOSTS[1]}:2380,${NAMES[2]}=https://${ETCDHOSTS[2]}:2380,${NAMES[3]}=https://${ETCDHOSTS[3]}:2380,${NAMES[4]}=https://${ETCDHOSTS[4]}:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

#[Security]
ETCD_CERT_FILE="/data/etcd/ssl/server.pem"
ETCD_KEY_FILE="/data/etcd/ssl/server-key.pem"
ETCD_TRUSTED_CA_FILE="/data/etcd/ssl/ca.pem"
ETCD_CLIENT_CERT_AUTH="true"
ETCD_PEER_CERT_FILE="/data/etcd/ssl/server.pem"
ETCD_PEER_KEY_FILE="/data/etcd/ssl/server-key.pem"
ETCD_PEER_TRUSTED_CA_FILE="/data/etcd/ssl/ca.pem"
ETCD_PEER_CLIENT_CERT_AUTH="true"
EOF

    cat << EOF | tee ./"${HOST}"/etcd.service
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target

[Service]
Type=notify
EnvironmentFile=/data/etcd/cfg/etcd.conf
ExecStart=/data/etcd/bin/etcd
Restart=on-failure
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

    cat << EOF | tee ./"${HOST}"/init-etcd.sh
#!/bin/bash
mkdir /data/etcd/{bin,cfg,ssl} -p

# 初始化etcd
tar zxf etcd-v3.4.16-linux-amd64.tar.gz
mv ./etcd-v3.4.16-linux-amd64/etcd*  /data/etcd/bin/

cp ./cert/*  /data/etcd/ssl/
cp ./etcd.conf  /data/etcd/cfg/
cp ./etcd.service   /usr/lib/systemd/system/

systemctl  daemon-reload
systemctl  enable etcd.service
systemctl  start etcd.service
sleep 2

if [ \$? -eq 0]; then
    echo -e "\033[32m  etcd start OK !  \033"
    /data/etcd/bin/etcdctl --cacert=/data/etcd/ssl/ca.pem --cert=/data/etcd/ssl/server.pem --key=/data/etcd/ssl/server-key.pem --endpoints="https://${ETCDHOSTS[0]}:2379,https://${ETCDHOSTS[1]}:2379,https://${ETCDHOSTS[2]}:2379,https://${ETCDHOSTS[3]}:2379,https://${ETCDHOSTS[4]}:2379"  endpoint health --write-out=table
else
    echo -e "\033[31m  etcd start failed !!!  \033"
fi

EOF

    tar zcf /tmp/"${HOST}".tar.gz ./"${HOST}"

    done
}

main () {
    cfssl_init
    sleep 5
    service_init
}

# 触发 
main